package com.imooc.pan.storage.engine.local;

import com.imooc.pan.storage.engine.core.AbstractStorageEngine;
import com.imooc.pan.storage.engine.core.context.*;
import com.imooc.pan.storage.engine.local.config.LocalStorageEngineConfig;
import com.imooc.pan.web.core.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;

/**
 * @Description: 本地的文件存储引擎实现方案
 * @Author: 张广焱
 * @Date: 2024-11-07 17:35
 */
@Component
public class LocalStorageEngine extends AbstractStorageEngine {
    @Autowired
    private LocalStorageEngineConfig config;

    /**
     * @Description: 执行删除物理文件的动作   下沉到具体的子类去实现
     * @Author: 张广焱
     * @Date: 2024-11-08  14:24:47
     */
    @Override
    protected void doDelete(DeleteFileContext context) throws IOException {
        FileUtils.deleteFiles(context.getRealFilePathList());
    }

    /**
     * @Description: 执行保存物理文件的动作   下沉到具体的子类去实现
     * @Author: 张广焱
     * @Date: 2024-11-08  14:25:20
     */
    @Override
    protected void doStore(StoreFileContext context) throws IOException {
        String basePath = config.getRootFilePath();
        //获取文件路径
        String realFilePath = FileUtils.generateStoreFileRealPath(basePath, context.getFilename());
//        将文件的输入流写入到文件中
        FileUtils.writeStream2File(context.getInputStream(), new File(realFilePath), context.getTotalSize());
        context.setRealPath(realFilePath);
    }

    @Override
    protected void doStoreChunk(StoreFileChunkContext context) throws IOException {
        String basePath = config.getRootFileChunkPath();
        //获取文件路径
        String realFilePath = FileUtils.generateStoreFileChunkRealPath(basePath, context.getIdentifier(), context.getChunkNumber());
//        将文件的输入流写入到文件中
        FileUtils.writeStream2File(context.getInputStream(), new File(realFilePath), context.getTotalSize());
        context.setRealPath(realFilePath);

    }

    /**
     * @param context
     * @Description: 执行文件分片的动作 下沉到子类去实现
     * @Author: 张广焱
     * @Date: 2024-11-13  15:56:36
     */
    @Override
    protected void doMergeFile(MergeFileContext context) throws IOException {
        String basePath = config.getRootFilePath();
        String realFilePath = FileUtils.generateStoreFileRealPath(basePath, context.getFilename());
        FileUtils.createFile(new File(realFilePath));
        List<String> chunkPaths = context.getRealPathList();
        for (String chunkPath : chunkPaths) {
            FileUtils.appendWrite(Paths.get(realFilePath), new File(chunkPath).toPath());
        }
        FileUtils.deleteFiles(chunkPaths);
        context.setRealPath(realFilePath);
    }

    @Override
    public void doReadFile(ReadFileContext context) throws IOException {
        File file = new File(context.getRealPath());
        FileUtils.writeFile2OutputStream(new FileInputStream(file), context.getOutputStream(), file.length());
    }

}
